package com.bolt.report.util;

import com.bolt.common.convert.Convert;
import com.bolt.common.utils.StrUtil;
import com.bolt.report.definition.*;
import com.bolt.report.engine.ReportConstants;
import com.bolt.report.exception.ReportException;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.DefaultIndexedColorMap;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.xssf.usermodel.XSSFFont;

import java.awt.*;

public class StyleUtil {


    private StyleUtil() {
        throw new UnsupportedOperationException();
    }

    public static Integer[] marginToValue(String margin) {
        String[] values = StrUtil.split(margin, ",");
        if (values.length != 4) {
            throw new ReportException("margin pattern error");
        }
        return Convert.toIntArray(values);
    }

    public static String toSizeUnit(float size) {
        return String.valueOf(size) + ReportConstants.DEFAULT_SIZ_UNIT;
    }

    public static String MMtoUnitPx(int size) {
        return String.valueOf(ToolUtil.mmToPixel(size)) + ReportConstants.DEFAULT_SIZ_UNIT;
    }

    public static String toStyle(StyleDefinition style) {
        StringBuilder builder = new StringBuilder();
        if (style == null) {
            return builder.toString();
        }
        if (style.getWidth() != 0) {
            builder.append("width:").append(toSizeUnit(ToolUtil.pixelToPoint(style.getWidth()))).append(";");
        }
        if (style.getHeight() != 0) {
            builder.append("height:").append(toSizeUnit(ToolUtil.pixelToPoint(style.getHeight()))).append(";");
        }
        if (style.getAlign() != null && style.getValign() != Align.normal) {
            builder.append("text-align:").append(style.getAlign().name()).append(";");
        }
        if (style.getValign() != null && style.getValign() != Align.normal) {
            builder.append("vertical-align:").append(style.getValign().name()).append(";");
        }
        if (StrUtil.isNotBlank(style.getBgcolor())) {
            builder.append("background:").append(style.getBgcolor()).append(";");
        }
        if (StrUtil.isNotBlank(style.getFontFamily())) {
            builder.append("font-family:").append(style.getFontFamily()).append(";");
        }
        if (style.getFontSize() != 0) {
            builder.append("font-size:").append(toSizeUnit(style.getFontSize())).append(";");
        }
        if (style.isBold()) {
            builder.append("font-weight:").append(FontWeight.bold).append(";");
        }
        if (style.isItalic()) {
            builder.append("font-style:").append(FontStyle.italic).append(";");
        }
        if (StrUtil.isNotBlank(style.getFontColor())) {
            builder.append("color:").append(style.getFontColor()).append(";");
        }
        if (null != style.getLeftBorder()) {
            BorderDefinition border = style.getLeftBorder();
            builder.append("border-left:" + border.getStyle() + " " + border.getWidth() + "px " + border.getColor() + ";");
        }
        if (null != style.getRightBorder()) {
            BorderDefinition border = style.getRightBorder();
            builder.append("border-right:" + border.getStyle() + " " + border.getWidth() + "px " + border.getColor() + ";");
        }
        if (null != style.getTopBorder()) {
            BorderDefinition border = style.getTopBorder();
            builder.append("border-top:" + border.getStyle() + " " + border.getWidth() + "px " + border.getColor() + ";");
        }
        if (null != style.getBottomBorder()) {
            BorderDefinition border = style.getBottomBorder();
            builder.append("border-bottom:" + border.getStyle() + " " + border.getWidth() + "px " + border.getColor() + ";");
        }
        return builder.toString();
    }

    public static StyleDefinition unionStyle(StyleDefinition sourceStyle, StyleDefinition targetStyle) {
        try {
            if (sourceStyle == null || targetStyle == null) {
                return null;
            }
            StyleDefinition style = sourceStyle.clone();
            if (sourceStyle.getWidth() != targetStyle.getWidth() && targetStyle.getWidth() != 0) {
                style.setWidth(targetStyle.getWidth());
            }
            if (sourceStyle.getHeight() != targetStyle.getHeight() && targetStyle.getHeight() != 0) {
                style.setWidth(targetStyle.getHeight());
            }
            if (style.getAlign() != targetStyle.getAlign() && targetStyle.getValign() != Align.normal) {
                style.setAlign(targetStyle.getValign());
            }
            if (style.getValign() != targetStyle.getValign() && targetStyle.getValign() != Align.normal) {
                style.setValign(targetStyle.getValign());
            }
            if (StrUtil.isNotBlank(targetStyle.getBgcolor())) {
                style.setBgcolor(targetStyle.getBgcolor());
            }
            if (StrUtil.isNotBlank(targetStyle.getFontFamily())) {
                style.setFontFamily(targetStyle.getFontFamily());
            }
            if (targetStyle.getFontSize() != 0) {
                style.setFontSize(targetStyle.getFontSize());
            }

            style.setBold(targetStyle.isBold());
            style.setItalic(targetStyle.isItalic());
            style.setUnderline(targetStyle.isUnderline());

            if (StrUtil.isNotBlank(targetStyle.getFontColor())) {
                style.setFontColor(targetStyle.getFontColor());
            }
            return style;
        } catch (Exception ex) {
            throw new ReportException("margin pattern error");
        }

    }

    public static XSSFCellStyle transformXlsStyle(SXSSFWorkbook wb, StyleDefinition cssStyle) {
        XSSFCellStyle style = (XSSFCellStyle) wb.createCellStyle();
        style.setWrapText(true);
        if (StrUtil.isNotBlank(cssStyle.getBgcolor())) {
            int[] rgb = hexColorToRgb(cssStyle.getBgcolor());
            style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            style.setFillForegroundColor(buildXSSFColor(rgb));
        }
        if (cssStyle.getAlign() != null && cssStyle.getValign() != Align.normal) {
            Align align = cssStyle.getAlign();
            if (align.equals(Align.left)) {
                style.setAlignment(HorizontalAlignment.LEFT);
            } else if (align.equals(Align.center)) {
                style.setAlignment(HorizontalAlignment.CENTER);
            } else if (align.equals(Align.right)) {
                style.setAlignment(HorizontalAlignment.RIGHT);
            }
        }
        if (cssStyle.getValign() != null && cssStyle.getValign() != Align.normal) {
            Align valign = cssStyle.getValign();
            if (valign.equals(valign.top)) {
                style.setVerticalAlignment(VerticalAlignment.TOP);
            } else if (valign.equals(Align.middle)) {
                style.setVerticalAlignment(VerticalAlignment.CENTER);
            } else if (valign.equals(Align.bottom)) {
                style.setVerticalAlignment(VerticalAlignment.BOTTOM);
            }
        }
        XSSFFont font = (XSSFFont) wb.createFont();
        if (StrUtil.isNotBlank(cssStyle.getFontFamily())) {
            font.setFontName(cssStyle.getFontFamily());
        }
        if (cssStyle.getFontSize() != 0) {
            font.setFontHeight(cssStyle.getFontSize());
        }
        font.setBold(cssStyle.isBold());
        if (StrUtil.isNotBlank(cssStyle.getFontColor())) {
            int[] rgb = hexColorToRgb(cssStyle.getFontColor());
            font.setColor(buildXSSFColor(rgb));
        }
        style.setFont(font);
        return style;
    }

    public static XSSFColor buildXSSFColor(int[] color) {
        Color c = new Color(color[0], color[1], color[2]);
        XSSFColor xssfColor = new XSSFColor(c, new DefaultIndexedColorMap());
        return xssfColor;
    }

    public static int[] hexColorToRgb(String hex) {
        String colorStr = hex;
        if (hex.startsWith("#")) {
            colorStr = hex.substring(1);
        }
        if (StringUtils.length(colorStr) == 8) {
            colorStr = hex.substring(2);
        }
        int r = Integer.valueOf(colorStr.substring(0, 2), 16);
        int g = Integer.valueOf(colorStr.substring(2, 4), 16);
        int b = Integer.valueOf(colorStr.substring(4, 6), 16);
        return new int[]{r, g, b};
    }


    public static String toMarginStyle(Integer top, Integer left, Integer bottom, Integer right) {
        StringBuilder builder = new StringBuilder();
        if (top != null && top != 0) {
            builder.append("top:").append(toSizeUnit( ToolUtil.mmToPoint(top))).append(";");
        }
        if (left != null && left != 0) {
            builder.append("left:").append(toSizeUnit(ToolUtil.mmToPoint(left))).append(";");
        }
        if (bottom != null && bottom != 0) {
            builder.append("bottom:").append(toSizeUnit(ToolUtil.mmToPoint(bottom))).append(";");
        }
        if (right != null && right != 0) {
            builder.append("right:").append(toSizeUnit(ToolUtil.mmToPoint(top))).append(";");
        }
        return builder.toString();
    }



}